package org.wak.dialog
{
	import org.wak.utils.ArrayIterator;
	import org.wak.utils.IIterator;
	
	/**
	 * This class is the atom of a conversation in the adventure. 
	 * 
	 */	
	public class Topic
	{
		private var mSay:Boolean = false ;
		private var mVisible:Boolean = true ;
		private var mAction:String = "" ;
		private var mActionTarget:String = "" ;
		private var mTopicId:String = "" ;
		
		
		private var mSaysArray:Array = null ;
		
		private var mOnlyOnce:Boolean = false ;
		private var mTopicPlayed:Boolean = false ;
		
		/**
		 * Constructor  
		 * @param pInput input xml containing the topic.
		 * 
		 */		
		public function Topic(pInput:XML)
		{
			mSay = pInput.@say == "true" ? true : false ;
			mVisible = pInput.@visible == "true" ? true : false ;
			mOnlyOnce = pInput.@onlyOnce == "true" ? true : false ;
			mAction = pInput.@action ;
			mActionTarget = pInput.@target ;
			mTopicId = pInput.@id ;

			mSaysArray = new Array();
			var fNewSayItem:SayItem = null ;
			for each( var say:XML in pInput.Say )
			{
				fNewSayItem = new SayItem( say.@speaker, say[0] );
				mSaysArray.push( fNewSayItem );
				//trace(mSaysArray);
			}			
		}
		
		/**
		 * Return the first found Say item for the given character id.
		 * @param The character id.
		 * @return Text to say for the character id in pCharId
		 * 
		 */		
		public function SayText(pCharId:String):String
		{
			var fFilterFunction:Function = function(item:SayItem, index:int, array:Array):Boolean
			{
				if( item.speakerId == pCharId )
					return true ;
					
				return false
			}
			var fSayText:SayItem = null ;
			var fResult:Array = mSaysArray.filter( fFilterFunction );
			if(fResult.length > 0)
			{
				fSayText = fResult[0] as SayItem ;
			}
			
			if(fSayText == null)
				return "";
			
			return fSayText.text ;
		}
		
		public function toString():String
		{
			return mTopicId ; 
		}
		
		/**
		 * Id of the topic, the id is optional fo the topic. 
		 * I must be used when some scripting interaction is used with the topic. 
		 * @return Topic id
		 * 
		 */		
		public function get topicId():String 
		{
			return mTopicId ;
		}
		
		/**
		 * If say is true the character will repeat the text after the selection. 
		 * @return 
		 * 
		 */		
		public function get say():Boolean 
		{
			return mSay ;
		}
		
		public function set say(value:Boolean):void 
		{
			mSay = value;
		}
		
		/**
		 * visibility flag for the topic on the dialog interface. 
		 * @return 
		 * 
		 */		
		public function get visible():Boolean 
		{
			return mVisible ;
		}
		
		public function set visible(value:Boolean):void 
		{
			mVisible = value;
		}
		
		/**
		 * List of the Say items contained in the Topic 
		 * @return IIterator with SayItem s
		 * 
		 */		
		public function GetSayItems():IIterator
		{
			return new ArrayIterator( mSaysArray );
		}
		
		/**
		 * Action of this topic.
		 * An action could be:
		 * exit: finish the conversation.
		 * goto: jumps to another dialog menu.
		 * activate: activates another dialgo option previously disabled.
		 * action: calls a method in the puzzle managers.
		 *  
		 * @return String with the action.
		 * 
		 */		
		public function get action():String
		{
			return mAction ;
		}
		
		/**
		 * The target works as a parameter of the action assigned to the topic.
		 * if the action of the topic is goto, the destination dialog is stored
		 * in the target property. 
		 * @return Target property.
		 * 
		 */		
		public function get target():String
		{
			return mActionTarget;
		}
		
		/**
		 * 
		 * true if this topic was played.
		 * 
		 */		
		public function set played(value:Boolean):void
		{
			mTopicPlayed = value;
		}
		
		/**
		 *@private 
		 */		
		public function get played():Boolean
		{
			return mTopicPlayed ;
		}
		
		/**
		 * True if this topic was intended to be played only once.
		 * 
		 */		
		public function get onlyOnce():Boolean
		{
			return mOnlyOnce ;
		}
		
		/**
		 * Test if a character is present in the topic. 
		 * @param pCharId character id to test.
		 * @return true if the character is present as speaker in the topic.
		 * 
		 */		
		public function isPresent(pCharId:String):Boolean
		{
			for each(var sayItem:SayItem in mSaysArray)
			{
				if( sayItem.speakerId == pCharId)
					return true ;
			}
			
			return false ;
		}


	}
}